import requests  # 导入requests库，用于发送HTTP请求
from bs4 import BeautifulSoup  # 导入BeautifulSoup库，用于解析HTML文档
import pandas as pd  # 导入pandas库，用于数据处理和生成DataFrame

# 目标URL，即我们要抓取的网页地址
url = "http://www.shanghairanking.cn/rankings/bcur/2020"

try:
    # 发送HTTP GET请求到目标URL
    resp = requests.get(url)
    # 检查请求是否成功，如果失败则抛出HTTPError异常
    resp.raise_for_status()

    # 获取网页的HTML内容
    html = resp.content

    # 使用BeautifulSoup解析HTML文档，'lxml'是解析器
    soup = BeautifulSoup(html, 'lxml')

    # 查找网页中的排名表格，这里假设表格的<table>标签是唯一的，实际情况可能需要根据HTML结构修改选择器
    ranking_table = soup.find('table')

    # 如果找到了排名表格
    if ranking_table:
        # 查找表格中的所有行<tr>
        rows = ranking_table.find_all('tr')
        # 初始化一个空列表，用于存储每行的数据
        list_of_rows = []

        # 遍历每一行
        for row in rows:
            # 查找行中的所有单元格<td>（这里排除了<th>，因为表格头部通常不包含我们需要的数据）
            cells = row.find_all(['td'])
            # 初始化一个空列表，用于存储当前行的数据
            row_data = []

            # 遍历当前行的每个单元格
            for i, cell in enumerate(cells, start=1):
                # 如果当前单元格是第二列（即学校中文名称），则特殊处理
                if i == 2:
                    # 在单元格中查找class为"name-cn"的元素，这通常是学校中文名称的容器
                    cell = cell.find(class_="name-cn")
                    # 如果找到了，则将其文本内容（去除前后空白）添加到行数据中
                    if cell:
                        row_data.append(cell.text.strip())
                        # 如果当前单元格是第六列（我们不需要的列，比如操作按钮等），则停止继续处理当前行的剩余单元格
                elif i == 6:
                    break
                    # 对于其他单元格，直接将其文本内容（去除前后空白）添加到行数据中
                else:
                    row_data.append(cell.text.strip())

                    # 如果当前行有数据（即非空行），则将其添加到列表中
            if row_data:
                list_of_rows.append(row_data)

                # 使用pandas库将列表转换为DataFrame，并指定列名
        df = pd.DataFrame(list_of_rows, columns=['排名', '学校名称', '省市', '学校类型', '总分'])
        # 打印DataFrame
        print(df)
    else:
        # 如果没有找到排名表格，则打印提示信息
        print('未找到排名表格。')
except requests.exceptions.RequestException as e:
    # 捕获requests库抛出的异常，并打印错误信息
    print(f'无法打开网址：{url}，错误：{e}')
except Exception as e:
    # 捕获其他所有异常，并打印错误信息
    print(f'发生错误：{e}')